﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace ArgusLib.Controls
{
	public class Button : System.Windows.Forms.Button
	{
		bool _Toggle = false;
		bool _Pressed = false;

		public Button()
			: base()
		{
			this.Padding = new System.Windows.Forms.Padding(5);
			this.UseVisualStyleBackColor = false;
			this.BackColor = Color.Black;
			this.ForeColor = Color.White;
			//this.autoSizeValue = this.Size;
		}

		public event EventHandler RotationChanged;
		public event EventHandler ToggleChanged;

		public bool Toggle
		{
			get { return this._Toggle; }
			set
			{
				bool changed = this._Toggle != value;
				this._Toggle = value;
				this.OnToggleChanged(EventArgs.Empty);
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool Pressed
		{
			get { return this._Pressed; }
			set
			{
				if (this.Toggle == true)
					this._Pressed = value;
			}
		}
		public Color BackColorPressed { get; set; }
		public Color ForeColorPressed { get; set; }

		/// <summary>
		/// Gets or sets a value specifying the angle the displayed text is rotated.
		/// </summary>
		/// <value>
		/// 0 = 0° Rotation,
		/// 1 = 90° Rotation,
		/// 2 = 190° Rotation,
		/// 3 = 270° Rotation
		/// </value>
		public int Rotation
		{
			get { return this._Rotation; }
			set
			{
				bool changed = this._Rotation != value;
				this._Rotation = value;
				if (changed == true)
					this.OnRotationChanged(EventArgs.Empty);
			}
		}
		int _Rotation;

		protected virtual void OnToggleChanged(EventArgs e)
		{
			if (this.Toggle == false)
				this._Pressed = false;
			if (this.ToggleChanged != null)
				this.ToggleChanged(this, e);
		}

		protected virtual void OnRotationChanged(EventArgs e)
		{
			//if (this.AutoSize == true)
			//	this.autoSizeValue = this.GetAutoSize();
			this.PerformLayout();
			if (this.RotationChanged != null)
				this.RotationChanged(this, e);
			//this.OnResize(e);
		}

		protected override void OnClick(EventArgs e)
		{
			if (this.Toggle == true)
			{
				this.Pressed = !this.Pressed;
				this.Refresh();
			}
			base.OnClick(e);
		}

		public override Size GetPreferredSize(Size proposedSize)
		{
			using (Graphics g = this.CreateGraphics())
			{
				SizeF size = g.MeasureString(this.Text, this.Font);
				if (this.Rotation % 2 == 1)
					size = new SizeF(size.Height, size.Width);
				Size RetVal = new Size((int)(size.Width + this.Padding.Horizontal), (int)(size.Height + this.Padding.Vertical));
				if (this.AutoSizeMode == System.Windows.Forms.AutoSizeMode.GrowOnly)
				{
					RetVal.Width = Math.Max(RetVal.Width, this.Width);
					RetVal.Height = Math.Max(RetVal.Height, this.Height);
				}
				return RetVal;
			}
		}

		protected override void OnPaint(PaintEventArgs pevent)
		{
			this.DrawBackground(pevent);
			this.DrawClientArea(pevent);
			this.DrawBorder(pevent);
		}

		protected virtual void DrawBackground(PaintEventArgs pevent)
		{
			pevent.Graphics.Clear(this.BackColor);
			//pevent.Graphics.FillRectangle(new SolidBrush(this.BackColor), pevent.ClipRectangle);
		}

		protected virtual void DrawClientArea(PaintEventArgs pevent)
		{
			Graphics g = pevent.Graphics;
			g.ResetTransform();
			SizeF size = g.MeasureString(this.Text, this.Font);
			if (size.Width > this.ClientSize.Width - this.Padding.Horizontal)
				size.Width = this.ClientSize.Width - this.Padding.Horizontal;
			g.TranslateTransform(-size.Width / 2, -size.Height / 2);
			g.RotateTransform(this.Rotation * 90, System.Drawing.Drawing2D.MatrixOrder.Append);
			g.TranslateTransform(size.Width / 2, size.Height / 2, System.Drawing.Drawing2D.MatrixOrder.Append);

			g.TranslateTransform((this.ClientSize.Width - size.Width) / 2.0f, (this.ClientSize.Height - size.Height) / 2.0f, System.Drawing.Drawing2D.MatrixOrder.Append);

			g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), 0, 0);
			g.ResetTransform();
		}

		protected virtual void DrawBorder(PaintEventArgs pevent)
		{
			Graphics g = pevent.Graphics;
			g.ResetTransform();
			if (this.Pressed == false)
			{
				g.DrawRectangle(new Pen(Color.Silver, 4),
					pevent.ClipRectangle.X + 2, pevent.ClipRectangle.Y + 2,
					pevent.ClipRectangle.Width - 3, pevent.ClipRectangle.Height - 3);
				g.DrawRectangle(Pens.Blue, pevent.ClipRectangle);
				g.DrawRectangle(Pens.LightBlue,
					pevent.ClipRectangle.X+1, pevent.ClipRectangle.Y+1,
					pevent.ClipRectangle.Width, pevent.ClipRectangle.Height);
			}
			else
			{
				g.DrawRectangle(new Pen(Color.Silver, 4),
					pevent.ClipRectangle.X + 1, pevent.ClipRectangle.Y + 1,
					pevent.ClipRectangle.Width - 2, pevent.ClipRectangle.Height - 2);
				g.DrawRectangle(Pens.Blue,
					pevent.ClipRectangle.X, pevent.ClipRectangle.Y,
					pevent.ClipRectangle.Width-1, pevent.ClipRectangle.Height-1);
				g.DrawRectangle(Pens.LightBlue,
					pevent.ClipRectangle.X+1, pevent.ClipRectangle.Y+1,
					pevent.ClipRectangle.Width - 3, pevent.ClipRectangle.Height - 3);
			}
		}
	}
}
